﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;

namespace GameWP
{
    public enum StateL
        {
            Stand,
            MoveRight,             
            Fight, 
            Dead,
            Skill,          // State đac biet eể dùng skill của luffy
            Disappear,      // State de xac dinh huy character do khoi man choi
            MoveLeft,       
            Unknow,         // State mac dinh khi chua xac dinh duoc State cua character, thuong dung cho preState
        };  
    public class Luffy : Character
    {
    #region Properties
        private Int64 _balance;
        public Int64 Balance
        {
            get { return _balance; }
            set { _balance = value; }
        }

        
        private int _hpLMax;
        private int _manaMax;
        private int _mana;
        public int Mana
        {
            get { return _mana; }
            set { _mana = value; }
        }

        private Button _levelBar;
        public Button LevelBar
        {
            get { return _levelBar; }
            set { _levelBar = value; }
        }

        private int _level;
        public int Level
        {
            get { return _level; }
            set { _level = value;
            _levelBar.Text = _level.ToString("00");
            }
        }

        private StateL _stateL;
        public StateL StateL
        {
            get { return _stateL; }
            set {
                if (_stateL != StateL.Skill)
                    _stateL = value;
            }
        }

        private StateL _preStateL;
        public StateL PreStateL
        {
            get { return _preStateL; }
            set { _preStateL = value;}
        }

        private int _intdexSkill; // indexSkill + _stateL ==> index thich hop voi cai skill hien tai trong ListTexture
        public int IntdexSkill
        {
            get { return _intdexSkill; }
            set {
                if (_stateL != StateL.Skill)
                {
                    _intdexSkill = value;
                    UseSkill(value);
                }
            }
        }

        private int _levelSkill; // co 6 level ung voi 6 skill cua Luffy
        public int LevelSkill
        {
            get { return _levelSkill; }
            set { _levelSkill = value; }
        }
        
        private List<Button> _listButtonSkill;
        public List<Button> ListButtonSkill
        {
            get { return _listButtonSkill; }
            set { _listButtonSkill = value; }
        }

        private List<int> _listAHeroHave;
        public List<int> ListAHeroHave
        {
            get { return _listAHeroHave; }
            set { _listAHeroHave = value; }
        }

        private List<int> _lisAHeronow;
        public List<int> LisAHeronow
        {
            get { return _lisAHeronow; }
            set { _lisAHeronow = value; }
        }

        private SpriteEffects _spriteEffect;
        public SpriteEffects SPriteEffect
        {
            get { return _spriteEffect; }
            set { _spriteEffect = value; }
        }

        private SpriteFont _spriteFont;
        public SpriteFont SpriteFont
        {
            get { return _spriteFont; }
            set { _spriteFont = value; }
        }

        private List<int> _listDamageSkill;
        public List<int> ListDamageSkill
        {
            get { return _listDamageSkill; }
            set { _listDamageSkill = value; }
        }

        private LuffyBar _LHpBar;
        public LuffyBar LHpBar
        {
            get { return _LHpBar; }
            set { _LHpBar = value; }
        }

        private LuffyBar _LManaBar;
        public LuffyBar LManaBar
        {
            get { return _LManaBar; }
            set { _LManaBar = value; }
        }

        private Button _BalanceBar;
        public Button BalanceBar
        {
            get { return _BalanceBar; }
            set { _BalanceBar = value; }
        }


        private List<int> _listManaForSkill;
        public List<int> ListManaForSkill
        {
            get { return _listManaForSkill; }
            set { _listManaForSkill = value; }
        }

        private int _levelScreen;
        public int LevelScreen
        {
            get { return _levelScreen; }
            set { _levelScreen = value; }
        }

        private bool _isStateView = false;
        public bool IsStateView
        {
            get { return _isStateView; }
            set { _isStateView = value; }
        }

        private int _preDamage;
        private float _preScaleRect;
        private float elapsedTime;
    #endregion

    #region Initiation
        public Luffy(List<Texture2D> listTextures,
            List<Texture2D> IconSkill,
            Vector2 posotion, 
            int hp,
            int damage,
            int mana,
            Int64 balance,
            int level,
            int levelSkill,
            int levelScreen,
            List<int> listAHeroHave,
            SpriteFont spriteFont,
            List<List<int>> seqTexture):base(listTextures, posotion, hp, damage, 0, 0, 0, 0, seqTexture)
        {
            _listTextures = listTextures;
            _position = posotion;
            _delay = 10;
            _seqTexture = seqTexture;
            _scaleTexture = 2;
            _listAHeroHave = listAHeroHave;
            _spriteFont = spriteFont;
            _rectangle = new Rectangle
                ((int)_position.X, (int)_position.Y, _listTextures[0].Width, _listTextures[0].Height);
            _scaleRect = 100; _preScaleRect = _scaleRect;
            _hp = hp; _hpLMax = _hp; _hpmax = _hpLMax;
            _mana = mana;        _manaMax = _mana;
            _damage = damage;    _preDamage = _damage;
            _speed = 10;
            _balance = balance;
            _indexTexture = 0;
            _level = level;
            _levelSkill = levelSkill;
            _intdexSkill = 1;
            _levelScreen = levelScreen;
            _stateL = StateL.Stand;
            _preStateL = StateL.Unknow;
            _spriteEffect = SpriteEffects.None;

            //HpBar
            _LHpBar = new LuffyBar(_hp, new Vector2(90, 37), Color.Red);
            //ManaBar
            _LManaBar = new LuffyBar(_mana, new Vector2(88, 59), Color.Blue) { Height = 11, Maxratio = 102 };
            //BalanceBar
            _BalanceBar = new Button(_balance.ToString(), _spriteFont, new Vector2(600, 90),Color.Black) { HaveSound = false };
            //LevelBar
            _levelBar = new Button(_level.ToString("00"), _spriteFont, new Vector2(25, 20));
            //List AHero Now            
            _lisAHeronow = new List<int>() { -1, -1, -1 };
            //List Button Skill
            _listManaForSkill = new List<int> { 30, 40, 100, 100, 150, 200 };
            _listButtonSkill = new List<Button>();
            for (int i = 0; i < IconSkill.Count; i++)
            {
                Button btSkill = new Button(IconSkill[i], new Vector2(730 - i * 70, 400)) { HaveSound = false };
                _listButtonSkill.Add(btSkill);
                _listButtonSkill[i].Selected += new Button.IsSelected(Luffy_Selected_Skill);
            }
        }

     
    #endregion

    #region Methods
        void Luffy_Selected_Skill(int input)
        {
            if (EnoughMana(input))
            {
                IntdexSkill = input;
                _stateL = StateL.Skill;
            }
        }

        private bool TouchMoveRight(Vector2 touchPosition)
        {
            Vector2 WorldPosition = ManagerGame.ScreenToWorld(touchPosition);
            if (_position.X < WorldPosition.X)
                return true;
            return false;
        }

        private void CheckTouchMove(Vector2 touchPosition)
        {
            if (_stateL != StateL.Skill)
            {
                if (touchPosition == Vector2.Zero)
                {
                    if (_stateL != StateL.Fight)
                    {
                        _stateL = StateL.Stand;
                        return;
                    }
                }
                else
                {
                    if (_stateL != StateL.Dead && _stateL != StateL.Skill)
                    {
                        if (TouchMoveRight(touchPosition))
                        {
                            if (_stateL != StateL.MoveRight)
                            {
                                _stateL = StateL.MoveRight;
                                return;
                            }
                        }
                        else
                        {
                            if (_stateL != StateL.MoveLeft)
                            {
                                _stateL = StateL.MoveLeft;
                                return;
                            }
                        }
                    };
                }
            }            
        }

        public bool CheckAttack(Character characterIsAttacked, GameTime gametime)
        {
            if (this.StateL == StateL.Dead || _hp < 0) return false;
            bool attack = false;
            if (this.IsCollisionWith(characterIsAttacked))
            {
                attack = true;
                this.StateL = StateL.Fight;
                double gt = gametime.TotalGameTime.TotalMilliseconds;
                if ((gt % characterIsAttacked.NormalDelay) < characterIsAttacked.Delay)
                {
                    if (_indexTexture >= _seqTexture[(int)StateL.Fight][(int)(_seqTexture[(int)StateL.Fight].Count / 3)])
                    characterIsAttacked.Hp -= this.Damage;
                    if (characterIsAttacked.Hp <= 0)
                        _balance += characterIsAttacked.Price;
                }
            }
            if (!attack)
                this.StateL = StateL.Stand;
            return attack;
        }

        private void UseSkill(int indexSkill)
        {
            _preDamage = _damage;
            _preScaleRect = _scaleRect;
            _mana -= _listManaForSkill[indexSkill];
            _listDamageSkill = new List<int>() { 30, 50, 40, 60, 40, 100 };
            switch (indexSkill)
            {
                //Update thuoc tinh khi chon skill
                case 0:     //Skill thu 0
                    if (ManagerGame.SoundOn) ManagerGame.managerSound._luffySoundEffect[0].Play();
                    _damage += 20;
                    _scaleRect += 100;
                    break;
                case 1:     //Skill thu 1 ...
                    if (ManagerGame.SoundOn) ManagerGame.managerSound._luffySoundEffect[1].Play();
                     _damage += 20;
                    break;
                case 2:
                    if (ManagerGame.SoundOn) ManagerGame.managerSound._luffySoundEffect[2].Play();
                    _damage += 30;
                    _scaleRect += 200;
                    break;
                case 3:
                    if (ManagerGame.SoundOn) ManagerGame.managerSound._luffySoundEffect[3].Play();
                     _damage += 40;
                    _scaleRect += 100;
                    break;
                case 4: // Far skill
                    if (ManagerGame.SoundOn) ManagerGame.managerSound._luffySoundEffect[4].Play();
                     _damage += 40;
                     _scaleRect += 80;
                    break;
                case 5:
                    if (ManagerGame.SoundOn) ManagerGame.managerSound._luffySoundEffect[5].Play();
                    _damage += 60;
                    _scaleRect += 200;
                    break;
            }
        }

        private void UnUseSkill()
        {
            _damage = _preDamage ;
            _scaleRect = _preScaleRect;
        }

        public bool EnoughMana(int indexSkill)
        {
            return _mana >= _listManaForSkill[indexSkill];
        }

        public void ResetLuffy(bool win) // sau khi qua 1 man choi reset mau va man ve max
        {
            if (win) _levelScreen++;
            else _balance = (int)(_balance / 2);
            _stateL = StateL.Stand;
            _hpmax = _hpLMax;
            _hp = _hpLMax; _mana = _manaMax;
            _position = new Vector2(50, 280);
            ManagerGame.camera.LookAt(_position);            
        }

        public void ResetLuffy() 
        {
            _hpmax = _hpLMax;
            _hp = _hpLMax; _mana = _manaMax;
            _position = new Vector2(50, 280);
        }

        public void Up2Level()
        {
            Level += 1;
            _hpLMax = (int)(_hpLMax * 1.17); _LHpBar.Maxhp = _hpLMax;
            _manaMax = (int)(_manaMax * 1.1); _LManaBar.Maxhp = _manaMax;
            _damage = (int)(_damage * 1.2);
            ResetLuffy();
        }

        private void UseFarSkill()
        {
            if (_spriteEffect == SpriteEffects.None)
            {
                if ((_position.X + _speed * 3) <= 1800)
                {
                    _position.X += _speed * 3;
                    ManagerGame.camera.Move(new Vector2(750.0f * elapsedTime, 0.0f), true);
                }
            }
            else
            {
                if ((_position.X - _speed * 3) >= 100)
                {
                    _position.X -= _speed * 3;
                    ManagerGame.camera.Move(new Vector2(-750.0f * elapsedTime, 0.0f), true);
                }
            }
            _rectangle.X = (int)_position.X;
            _rectangle.Y = (int)_position.Y;
        }
    #endregion

    #region Draw & Update
        #region Update
        public override void Update(GameTime gametime, Vector2 position)//position = touchposition
        {
            for (int i = 0; i < _levelSkill; i++)
            {
                if (_mana < _listManaForSkill[i]) _listButtonSkill[i].ColorTexture = Color.Blue;
                else _listButtonSkill[i].ColorTexture = Color.White;
                _listButtonSkill[i].ButtonIsTouched(position, i);
            }
            if (_stateL != StateL.Disappear)
            {
                double gt = gametime.TotalGameTime.Milliseconds;
                elapsedTime = (float)gametime.ElapsedGameTime.TotalSeconds;
                if (!_isStateView) CheckTouchMove(position); //position = touchposition
                if ((gt % NormalDelay) < 7)
                {
                    if (_mana < _manaMax) _mana += 1;
                    if (_hp < _hpLMax && _hp > 0) _hp += 1;
                }
                if ((gt % NormalDelay) < _delay)
                {
                    if (_hp <= -10) { _stateL = StateL.Dead;};
                    if (_hp < (int)(_hpLMax / 4))
                    {
                        if (_hp % 3 ==0 || _hp < 0)
                            _colorTexture = Color.Red;
                        else
                            _colorTexture = Color.White;
                    }
                    else _colorTexture = Color.White;
                    if (_preStateL == _stateL)
                    {
                        int intState = (int)_stateL;
                        _indexTexture += 1;
                        switch (_stateL)
                        {
                            case StateL.Stand:
                                break;
                            case StateL.MoveRight:
                                if (_position.X <= 1800)
                                {
                                    _position.X += _speed;
                                    _rectangle.X = (int)_position.X;
                                    _rectangle.Y = (int)_position.Y;
                                    ManagerGame.camera.Move(new Vector2(250.0f * elapsedTime, 0.0f), true);
                                }                                
                                break;
                            case StateL.MoveLeft:
                                if (_position.X >= 100 )
                                {
                                    _position.X -= _speed * 2;
                                    _rectangle.X = (int)_position.X;
                                    _rectangle.Y = (int)_position.Y;
                                    intState = (int)StateL.MoveRight;
                                    ManagerGame.camera.Move(new Vector2(-500.0f * elapsedTime, 0.0f), true);
                                }                                
                                break;
                            case StateL.Fight:
                                if (_indexTexture < 24)
                                    if (ManagerGame.SoundOn) ManagerGame.managerSound._luffySoundEffect[7].Play();
                                break;
                            case StateL.Dead:
                                break;
                            case StateL.Skill:
                                intState = (int)_stateL + _intdexSkill;
                                if (_intdexSkill == 4)
                                    UseFarSkill();
                                break;
                        }
                        if (_indexTexture > _seqTexture[intState][_seqTexture[intState].Count - 1])
                            if (_stateL == StateL.Dead)
                                _indexTexture = _seqTexture[intState][_seqTexture[intState].Count - 1];
                            else if (_stateL == StateL.Skill)
                            {
                                _stateL = StateL.Stand;
                                UnUseSkill();
                            }
                            else if (_stateL == StateL.Fight)
                            {                                
                                _indexTexture = _seqTexture[intState][0];
                            }
                            else _indexTexture = _seqTexture[intState][0];
                    }
                    else
                    {
                        _indexTexture = _seqTexture[(int)_stateL][0];
                        _preStateL = _stateL;
                        switch (_stateL)
                        {
                            case StateL.Stand:
                                break;
                            case StateL.MoveRight:
                                _spriteEffect = SpriteEffects.None;
                                break;
                            case StateL.MoveLeft:
                                _indexTexture = _seqTexture[(int)StateL.MoveRight][0];
                                _spriteEffect = SpriteEffects.FlipHorizontally;
                                break;
                            case StateL.Fight:
                                if (ManagerGame.SoundOn) ManagerGame.managerSound._luffySoundEffect[7].Play();
                                break;
                            case StateL.Dead:
                                break;
                            case StateL.Skill:
                                _indexTexture = _seqTexture[(int)StateL.Skill + _intdexSkill][0];
                                break;
                        }                        
                    }
                }
                _LHpBar.Update(gametime, _hp);
                _LManaBar.Update(gametime, _mana);
                _BalanceBar.Text = "$" + _balance.ToString();
            }      
        }
        #endregion
        
        #region Draw
        public override void Draw(SpriteBatch spritebatch, GameTime gametime)
        {
            //Vector2 realPosition = ManagerGame.WorldToScreen(_position);
            spritebatch.Draw(_listTextures[_indexTexture], _position, null, _colorTexture, 0, Vector2.Zero, _scaleTexture, _spriteEffect, 0);
            /*_LHpBar.Draw(spritebatch, gametime);
            _LManaBar.Draw(spritebatch, gametime);
            _BalanceBar.Draw(spritebatch, gametime);
            _levelBar.Draw(spritebatch, gametime);
            for (int i = 0; i < _levelSkill; i++)
                _listButtonSkill[i].Draw(spritebatch, gametime);*/
        }
        #endregion
        
    #endregion
    }
}
